package com.sapitest.utils;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.sapitest.utils.bean.Response;
import org.apache.http.Consts;
import org.apache.http.Header;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpHead;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import static com.sapitest.utils.ca.CertificateValidationIgnored.buildSSLCloseableHttpClient;

/**
 * HTTP请求工具类，目前封装post,get,head请求
 * @date 2019-01-13
 * @author Liuxu
 * @version 1.0.0
 * @since jdk1.8
 */
public class HttpMethod {
    private static final Logger logger = LoggerFactory.getLogger(HttpHead.class);
    private static RequestConfig config;
    private static int connectionRequestTimeout = Integer.parseInt(ConfigFile.getSystemParameter("http_connection_request_timeout"));
    private static int connectTimeout = Integer.parseInt(ConfigFile.getSystemParameter("http_connect_timeout"));
    private static int socketTimeout = Integer.parseInt(ConfigFile.getSystemParameter("http_socket_timeout"));

    public HttpMethod(){
        config = RequestConfig.custom()
                .setConnectionRequestTimeout(connectionRequestTimeout)
                .setConnectTimeout(connectTimeout)
                .setSocketTimeout(socketTimeout)
                .build();
    }

    /**
     * post请求
     * @param url String
     * @param header String
     * @param requestBody String
     * @return 自定义Response
     */
    public Response post(String url, String header, String requestBody) throws IOException {
        CloseableHttpClient httpclient = buildSSLCloseableHttpClient();
        HttpPost httppost = new HttpPost(url);
        httppost.setConfig(config);
        if (null != header && !"".equals(header)) {
            for (Map.Entry<String, String> entry : getRequestHeader(header).entrySet()) {
                httppost.setHeader(entry.getKey(), entry.getValue());
            }
        }
        httppost.setEntity(new StringEntity(requestBody));
        CloseableHttpResponse response = httpclient.execute(httppost);
        return getResponse(response);
    }

    /**
     * get请求
     * @param url String
     * @param header String
     * @return 自定义Response
     */
    public Response get(String url, String header) throws IOException {
        new HttpMethod();
        CloseableHttpClient httpclient = buildSSLCloseableHttpClient();
        HttpGet httpget = new HttpGet(url);
        httpget.setConfig(config);
        if (null != header && !"".equals(header)) {
            for (Map.Entry<String, String> entry : getRequestHeader(header).entrySet()) {
                httpget.setHeader(entry.getKey(), entry.getValue());
            }
        }
        CloseableHttpResponse response = httpclient.execute(httpget);
        return getResponse(response);
    }

    /**
     * head请求
     * @param url String
     * @param header String
     * @return 自定义Response
     */
    public Response head(String url, String header) throws IOException {
        new HttpMethod();
        CloseableHttpClient httpclient = buildSSLCloseableHttpClient();
        HttpHead httphead = new HttpHead(url);
        httphead.setConfig(config);
        if (null != header && !"".equals(header)) {
            for (Map.Entry<String, String> entry : getRequestHeader(header).entrySet()) {
                httphead.setHeader(entry.getKey(), entry.getValue());
            }
        }
        CloseableHttpResponse response = httpclient.execute(httphead);
        return getResponse(response);
    }

    /**
     * 获取请求体中的头部信息，转化为HashMap
     * @param header 字符串String类型，格式[{"key1":"value1"},{"key2":"value2"},{"key3":"value3"}]
     * @return Map<String, String>
     */
    private Map<String, String> getRequestHeader(String header){
        Map<String, String> headerMap = new HashMap<>();
        JSONArray headerArray = JSONArray.parseArray(header);
        for (int i=0; i<headerArray.size(); i++){
            JSONObject headerObject = headerArray.getJSONObject(i);
            for (String key : headerObject.keySet()){
                headerMap.put(key, headerObject.getString(key));
            }
        }
        return headerMap;
    }

    /**
     * 获取response的header
     * @param headers Header[]
     * @return Map<String, String>
     */
    private Map<String, String> getResponseHeader(Header[] headers){
        if (null != headers) {
            Map<String, String> headerMap = new HashMap<>();
            for (Header header : headers) {
                headerMap.put(header.getName(), header.getValue());
            }
            return headerMap;
        }
        return null;
    }

    /**
     * 获取自定义Response
     * @param response CloseableHttpResponse
     * @return Response
     */
    private Response getResponse(CloseableHttpResponse response){
        Response res = null;
        try {
            res = new Response();
            res.setResponseCode(response.getStatusLine().getStatusCode());
            res.setResponseHeader(getResponseHeader(response.getAllHeaders()));
            res.setResponseBody(EntityUtils.toString(response.getEntity(), Consts.UTF_8));
        } catch (IOException e) {
            logger.error(e.getMessage());
        } finally {
            try {
                response.close();
            } catch (IOException e) {
                logger.error(e.getMessage());
            }
        }
        return res;
    }
}
